package com.suray.wcs.service.system.entity;

import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonValue;
import com.suray.basic.wcs.path.core.Node;
import com.suray.commin.annotation.Excel;
import com.suray.wcs.service.enums.TaskRgvProgress;
import com.suray.wcs.service.enums.TaskStatus;
import com.suray.wcs.service.enums.TaskType;
import com.suray.wcs.service.init.SystemInit;
import com.suray.commin.core.utils.BaseModel;
import com.suray.wcs.service.pojo.Rgv;
import com.suray.wcs.service.task.TaskDescription;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

/**
 * <p>
 *
 * </p>
 *
 * @author cooper
 * @since 2019-06-26
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("wcs_task")
public class TaskDB extends BaseModel implements Serializable, Comparable<TaskDB> {

    private static final long serialVersionUID = 1L;

    @TableId(value = "task_id", type = IdType.AUTO)
    @Excel(name = "任务ID", cellType = Excel.ColumnType.NUMERIC, prompt = "任务ID")
    private Integer taskId;

    @Excel(name = "托盘码")
    private String barCode;

    @Excel(name = "PLC编号")
    private Integer plcId;

    @Excel(name = "上报时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT)
    private Date commitTime;

    @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT)
    private Date completeTime;

    //任务耗时
    @Excel(name = "耗时")
    private String timeConsuming;

    @Excel(name = "最终目的坐标")
    private String endNodeStr;

    @Excel(name = "可用的出库库口")
    private String outPortsStr;

    @Excel(name = "执行时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT)
    private Date executeTime;

    @Excel(name = "库口编码")
    private String taskPortId;

    @Excel(name = "小车进度")
    private TaskRgvProgress rgvProgress;

    /**
     * 500 默认
     * 1000 充电任务
     * 10001, 无法恢复的死锁、车辆运行过程中请求PLC并遇见PLC异常（WcsTimeoutException、PlcExecuteExecption）
     * 11001, 外形检测
     * 18888, 避让任务
     * 20000任务生成接口 手动添加任务
     * bean.getPriority() 任务接收
     * wmsTask.getPriorityCode(); 接收上位任务
     */
    @Excel(name = "优先级")
    private Integer priorityCode;

    @Excel(name = "起始坐标")
    private String startNodeStr;

    @Excel(name = "PLC进度", readConverterExp = "0=等待,-90=所有设备任务完成（除小车）")
    private Integer plcProgress;

    @Excel(name = "任务状态")
    private TaskStatus taskStatus;

    @Excel(name = "任务类型")
    private TaskType taskType;

    @Excel(name = "WMS编号")
    private String wmsTaskId;

    @Excel(name = "前置任务")
    private Integer preTaskId;
    /**
     * 实际分配车辆编号
     */
    @Excel(name = "执行车辆")
    private Integer processingRgvNo;
    /**
     * 当前任务是否允许分配车辆(达到分配的条件)
     * 入库任务输送线执行到某个阶段设置该字段
     * 接驳任务前置任务执行到某个阶段设置该字段
     * 其他情况 同理
     */
    private Boolean allowAssignmentRgv;
    /**
     * 预分配车辆编号
     */
    @Excel(name = "预分配车辆")
    private Integer preProcessingRgvNo;

    private String taskProgrammeGridId;

    @Excel(name = "初始目的坐标")
    private String originalEndNodeStr;
    /**
     * 相关联的任务组号
     */
    private String groupId;

    @TableField(exist = false)
    private String plcProgressStr;

    @TableField(exist = false)
    private String color;

    @TableField(exist = false)
    @JSONField(serialize = false)
    private TaskDB preTask;

    @TableField(exist = false)
    private Integer taskStatusGroup;

    //自卸式提升机提升机路径,自卸式提升机待测试暂时不支持使用
    @TableField(exist = true)//使用时改成true
    private String lifterPath;

    /**
     * 车道起点耗时
     */
    private Integer toStartTime;
    /**
     * 起点到终点耗时
     */
    private Integer startToEndTime;
    /**
     * 该标志下的任务只能分给同一个车
     */
    private String singleRgvFlag;
    /**
     * 移库任务，终点对应的巷道，只有移库任务有
     */
    private String groupIdSecond;

    /**
     * 库区可能划分多个分区
     */
    private Integer zoneId;

    @Excel(name = "异常信息")
    private String tips;

    /**
     * 节点限制执行任务车数量标识
     */
    private Integer nodeLimitRgvFlag;

    /**
     * 移库终点节点限制执行任务车数量标识
     */
    private Integer transEndNodeLimitRgvFlag;

    /**
     * 跑码路径
     */
    private String path;

    /**
     * 当前任务关联任务id
     */
    private Integer connectTaskId;

    /**
     * 任务描述
     */
    @TableField(exist = false)
    private TaskDescription taskDescription;

    /**
     * 任务描述
     */
    @TableField(exist = false)
    private String description;

    /**
     * 前置接驳点
     */
    @TableField(exist = false)
    private Node preConnect;

    /**
     * 后置接驳点
     */
    @TableField(exist = false)
    private Node sufConnect;

    /**
     * 接驳点库口
     */
    @TableField(exist = false)
    private String connectPortCode;

    /**
     * 补充任务类型
     */
    private Integer subTaskType;

    public TaskDB() {
        taskDescription = new TaskDescription();
    }

    public void setEndNode(Node endNode) {
        this.endNodeStr = endNode == null ? null : endNode.toString();
    }

    /**
     * 所有的不需要和前端交互的方法不要用get开头的方法，会有未知bug的
     *
     * @return
     */
    public Node selectEndNode() {
        return endNodeStr == null || endNodeStr.equals("") ? null : Node.parseGrid(endNodeStr);
    }

    public void setStartNode(Node startNode) {
        this.startNodeStr = startNode == null ? null : startNode.toString();
    }

    public Node selectStartNode() {
        return startNodeStr == null || startNodeStr.equals("") ? null : Node.parseGrid(startNodeStr);
    }

    /**
     * 查询该任务执行车辆对象
     *
     * @return
     */
    public Rgv selectProcessingRgvPojo() {
        return this.getProcessingRgvNo() == null ? null : SystemInit.getByRgvNoTask(this.getProcessingRgvNo());
    }

    public TaskType selectTaskTypeEnum() {
        return taskType;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
//        if (!super.equals(o)) return false;
        TaskDB taskdb = (TaskDB) o;
        return taskId.equals(taskdb.taskId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), taskId);
    }

    @Override
    public int compareTo(TaskDB o) {
        if (Integer.compare(o.getPriorityCode(), this.getPriorityCode()) == 0) {
            return Integer.compare(this.getTaskId(), o.getTaskId());
        } else {
            return Integer.compare(o.getPriorityCode(), this.getPriorityCode());
        }

    }
}
